namespace Terra.Core.Common.Utils;
using System.Text;
using System.Web;

/// <summary>
/// 字符串工具类
/// </summary>
public static class StringUtils
{
    #region 基础字符串操作

    /// <summary>
    /// 检查字符串是否为空或空白
    /// </summary>
    public static bool IsNullOrWhiteSpace(string value) => value.IsEmpty();

    /// <summary>
    /// 安全的字符串截取，超出长度时返回可用最大长度的字符串
    /// </summary>
    public static string SafeSubstring(string value, int startIndex, int length) =>
        value.SafeSubstring(startIndex, length);

    #endregion

    #region 命名转换

    /// <summary>
    /// 转换为驼峰命名
    /// </summary>
    public static string ToCamelCase(string value) => value.ToCamelCase();

    /// <summary>
    /// 转换为帕斯卡命名
    /// </summary>
    public static string ToPascalCase(string value) => value.ToPascalCase();

    /// <summary>
    /// 转换为下划线命名
    /// </summary>
    public static string ToSnakeCase(string value) => value.ToSnakeCase();

    #endregion

    #region 项目特定扩展

    /// <summary>
    /// 获取字符串的显示名称（用于UI显示）
    /// 规则：
    /// 1. 如果长度超过maxLength，截取前maxLength-3个字符并加上...
    /// 2. 如果是null，返回默认值
    /// </summary>
    public static string GetDisplayName(string value, int maxLength = 20, string defaultValue = "-")
    {
        if (value.IsEmpty()) return defaultValue;
        if (value.Length <= maxLength) return value;
        return value.SafeSubstring(0, maxLength - 3) + "...";
    }

    /// <summary>
    /// 移除HTML标签
    /// </summary>
    public static string StripHtml(string html)
    {
        if (html.IsEmpty()) return string.Empty;
        return System.Text.RegularExpressions.Regex.Replace(html, "<.*?>", string.Empty);
    }

    /// <summary>
    /// 格式化文件大小
    /// </summary>
    public static string FormatFileSize(long bytes)
    {
        string[] sizes = { "B", "KB", "MB", "GB", "TB" };
        double len = bytes;
        int order = 0;
        while (len >= 1024 && order < sizes.Length - 1)
        {
            order++;
            len = len / 1024;
        }
        return $"{len:0.##} {sizes[order]}";
    }

    #endregion

    #region URL编码解码

    /// <summary>
    /// 对字符串进行URL安全的Base64编码
    /// </summary>
    /// <param name="input">要编码的字符串</param>
    /// <returns>URL安全的Base64编码字符串</returns>
    public static string ToUrlSafeBase64(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return input;

        try
        {
            byte[] inputBytes = Encoding.UTF8.GetBytes(input);
            return Convert.ToBase64String(inputBytes)
                .TrimEnd('=')  // 移除末尾的等号
                .Replace('+', '-')  // 替换加号为减号
                .Replace('/', '_'); // 替换斜杠为下划线
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("URL安全的Base64编码失败", ex);
        }
    }

    /// <summary>
    /// 将URL安全的Base64编码字符串解码为原始字符串
    /// </summary>
    /// <param name="urlSafeBase64">URL安全的Base64编码字符串</param>
    /// <returns>解码后的原始字符串</returns>
    public static string FromUrlSafeBase64(this string urlSafeBase64)
    {
        if (string.IsNullOrEmpty(urlSafeBase64))
            return urlSafeBase64;

        try
        {
            string base64 = urlSafeBase64
                .Replace('-', '+')  // 还原加号
                .Replace('_', '/'); // 还原斜杠

            // 补充Base64填充
            switch (base64.Length % 4)
            {
                case 2: base64 += "=="; break;
                case 3: base64 += "="; break;
            }

            byte[] bytes = Convert.FromBase64String(base64);
            return Encoding.UTF8.GetString(bytes);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("URL安全的Base64解码失败", ex);
        }
    }

    /// <summary>
    /// URL编码（使用UTF-8编码）
    /// </summary>
    /// <param name="url">要编码的URL</param>
    /// <returns>编码后的URL</returns>
    public static string UrlEncode(this string url)
    {
        if (string.IsNullOrEmpty(url))
            return url;

        try
        {
            return HttpUtility.UrlEncode(url, Encoding.UTF8);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("URL编码失败", ex);
        }
    }

    /// <summary>
    /// URL解码（使用UTF-8编码）
    /// </summary>
    /// <param name="encodedUrl">已编码的URL</param>
    /// <returns>解码后的URL</returns>
    public static string UrlDecode(this string encodedUrl)
    {
        if (string.IsNullOrEmpty(encodedUrl))
            return encodedUrl;

        try
        {
            return HttpUtility.UrlDecode(encodedUrl, Encoding.UTF8);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("URL解码失败", ex);
        }
    }

    /// <summary>
    /// 处理包含特殊字符的URL参数值
    /// </summary>
    /// <param name="paramValue">参数值</param>
    /// <returns>处理后的参数值</returns>
    public static string EncodeUrlParameter(this string paramValue)
    {
        if (string.IsNullOrEmpty(paramValue))
            return paramValue;

        try
        {
            // 先进行URL编码，然后处理特殊字符
            return HttpUtility.UrlEncode(paramValue, Encoding.UTF8)
                ?.Replace("+", "%20") // 确保空格被编码为%20而不是+
                ?? paramValue;
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("URL参数编码失败", ex);
        }
    }

    /// <summary>
    /// 解码URL参数值
    /// </summary>
    /// <param name="encodedValue">已编码的参数值</param>
    /// <returns>解码后的参数值</returns>
    public static string DecodeUrlParameter(this string encodedValue)
    {
        if (string.IsNullOrEmpty(encodedValue))
            return encodedValue;

        try
        {
            // 先将%20转换回+，然后进行URL解码
            return HttpUtility.UrlDecode(
                encodedValue.Replace("%20", "+"),
                Encoding.UTF8);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("URL参数解码失败", ex);
        }
    }

    #endregion
}